/*
 * Copyright (C) 2020 Agrui
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdlib.h>
#include <string.h>
#include <memory.h>
#include <Event.h>
#include <Registrant.h>
#include <AsyncResult.h>
#include <OSMemory.h>

#include <RegistrantList.h>
#include <ParameterCheck.h>

static Bundle getBundle() {
    SELF_PREPARE(Event);

    if (!self) {
        return INVALID_BUNDLE_HANDLE;
    }

    return self->mBundle;
}

static char* getName() {
    SELF_PREPARE(Event);
    return (char*)self->mNickName;
}

static boolean getState() {
    SELF_PREPARE(Event);
    return self->mState;
}

static void notifyStateChanged(Event* self) {
    AsyncResult ar;
    EventData eventData = {0};
    strcpy(eventData.mNickName, self->mNickName);
    eventData.mState = self->mState;
    ar.result = &eventData;
    ar.resultSize = sizeof(eventData);
    registrantListNotifyRegistrants(self->mRegList, &ar);
}


static void updateState(boolean state) {
    SELF_PREPARE(Event);
    if (self->mState != state) {
        self->mState = state;
        notifyStateChanged(self);
        if (state && self->mAutoReset) {
            self->mState = FALSE;
            notifyStateChanged(self);
        }
    }
}

static void autoResetState() {
    SELF_PREPARE(Event);
    if (self->mAutoReset) {
        self->mState = FALSE;
    }
}

static void registerStateChanged(Handler* handler, int what, void* obj) {
    SELF_PREPARE(Event);
    PARAMTER_CHECK_RETURN_VOID(self);
    registrantListAdd(self->mRegList, handler, what, obj);
}
static void unregisterStateChanged(Handler* handler) {
    SELF_PREPARE(Event);
    PARAMTER_CHECK_RETURN_VOID(self);
    registrantListRemove(self->mRegList, handler);
}


static void __init__(Event* self, const char* name, boolean state, boolean autoReset) {
    self->mRegList = newRegistrantList();
    if (!self->mRegList) {
        return;
    }

    strncpy(self->mNickName, name, MAX_NICK_NAME_LEN-1);
    self->mState = state;
    self->mAutoReset = autoReset;
}

static void __deinit__(Event* self) {
    if (self->mRegList) {
        deleteRegistrantList(self->mRegList);
    }
}

DEF_CLASS_METHOD(Event, __init__, __init__);
DEF_CLASS_METHOD(Event, __deinit__, __deinit__);

LOAD_CLASS_ARG3(Event, const char*, boolean, boolean) {
    SET_MEMBER(Event, __init__);
    SET_MEMBER(Event, __deinit__);
    OBJ_BIND(Event, getName);
    OBJ_BIND(Event, getBundle);
    OBJ_BIND(Event, getState);
    OBJ_BIND(Event, updateState);
    OBJ_BIND(Event, autoResetState);
    OBJ_BIND(Event, registerStateChanged);
    OBJ_BIND(Event, unregisterStateChanged);
}



